home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / POV-Ray 3.0.2 / src / SOURCE / TRIANGLE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-25  |  26.5 KB  |  1,408 lines  |  [TEXT/CWIE]

  1. /****************************************************************************
  2. *                triangle.c
  3. *
  4. *  This module implements primitives for triangles and smooth triangles.
  5. *
  6. *  from Persistence of Vision(tm) Ray Tracer
  7. *  Copyright 1996 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. *  NOTICE: This source code file is provided so that users may experiment
  10. *  with enhancements to POV-Ray and to port the software to platforms other
  11. *  than those supported by the POV-Ray Team.  There are strict rules under
  12. *  which you are permitted to use this file.  The rules are in the file
  13. *  named POVLEGAL.DOC which should be distributed with this file. If
  14. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  16. *  Forum.  The latest version of POV-Ray may be found there as well.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23.  
  24. #include "frame.h"
  25. #include "povray.h"
  26. #include "vector.h"
  27. #include "povproto.h"
  28. #include "matrices.h"
  29. #include "objects.h"
  30. #include "triangle.h"
  31.  
  32.  
  33.  
  34. /*****************************************************************************
  35. * Local preprocessor defines
  36. ******************************************************************************/
  37.  
  38. #define DEPTH_TOLERANCE 1e-6
  39.  
  40. #define max3_coordinate(x,y,z) \
  41.   ((x > y) ? ((x > z) ? X : Z) : ((y > z) ? Y : Z))
  42.  
  43.  
  44.  
  45. /*****************************************************************************
  46. * Static functions
  47. ******************************************************************************/
  48.  
  49. static void find_triangle_dominant_axis PARAMS((TRIANGLE *Triangle));
  50. static void compute_smooth_triangle  PARAMS((SMOOTH_TRIANGLE *Triangle));
  51. static int Intersect_Triangle  PARAMS((RAY *Ray, TRIANGLE *Triangle, DBL *Depth));
  52. static int All_Triangle_Intersections  PARAMS((OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack));
  53. static int Inside_Triangle  PARAMS((VECTOR IPoint, OBJECT *Object));
  54. static void Triangle_Normal  PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
  55. static void *Copy_Triangle  PARAMS((OBJECT *Object));
  56. static void Translate_Triangle  PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  57. static void Rotate_Triangle  PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  58. static void Scale_Triangle  PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  59. static void Transform_Triangle  PARAMS((OBJECT *Object, TRANSFORM *Trans));
  60. static void Invert_Triangle  PARAMS((OBJECT *Object));
  61. static void Smooth_Triangle_Normal  PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
  62. static void *Copy_Smooth_Triangle PARAMS((OBJECT *Object));
  63. static void Translate_Smooth_Triangle  PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  64. static void Rotate_Smooth_Triangle  PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  65. static void Scale_Smooth_Triangle  PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  66. static void Transform_Smooth_Triangle  PARAMS((OBJECT *Object, TRANSFORM *Trans));
  67. static void Invert_Smooth_Triangle  PARAMS((OBJECT *Object));
  68. static void Destroy_Triangle  PARAMS((OBJECT *Object));
  69.  
  70.  
  71.  
  72. /*****************************************************************************
  73. * Local variables
  74. ******************************************************************************/
  75.  
  76. METHODS Triangle_Methods =
  77. {
  78.   All_Triangle_Intersections,
  79.   Inside_Triangle, Triangle_Normal,
  80.   Copy_Triangle,
  81.   Translate_Triangle, Rotate_Triangle,
  82.   Scale_Triangle, Transform_Triangle, Invert_Triangle, Destroy_Triangle
  83. };
  84.  
  85. METHODS Smooth_Triangle_Methods =
  86. {
  87.   All_Triangle_Intersections,
  88.   Inside_Triangle, Smooth_Triangle_Normal,
  89.   Copy_Smooth_Triangle,
  90.   Translate_Smooth_Triangle, Rotate_Smooth_Triangle,
  91.   Scale_Smooth_Triangle, Transform_Smooth_Triangle,
  92.   Invert_Smooth_Triangle, Destroy_Triangle
  93. };
  94.  
  95.  
  96. /*****************************************************************************
  97. *
  98. * FUNCTION
  99. *
  100. *   find_triangle_dominant_axis
  101. *
  102. * INPUT
  103. *   
  104. * OUTPUT
  105. *   
  106. * RETURNS
  107. *   
  108. * AUTHOR
  109. *
  110. *   POV-Ray Team
  111. *   
  112. * DESCRIPTION
  113. *
  114. *   -
  115. *
  116. * CHANGES
  117. *
  118. *   -
  119. *
  120. ******************************************************************************/
  121.  
  122. static void find_triangle_dominant_axis(Triangle)
  123. TRIANGLE *Triangle;
  124. {
  125.   DBL x, y, z;
  126.  
  127.   x = fabs(Triangle->Normal_Vector[X]);
  128.   y = fabs(Triangle->Normal_Vector[Y]);
  129.   z = fabs(Triangle->Normal_Vector[Z]);
  130.  
  131.   Triangle->Dominant_Axis = max3_coordinate(x, y, z);
  132. }
  133.  
  134.  
  135.  
  136. /*****************************************************************************
  137. *
  138. * FUNCTION
  139. *
  140. *   compute_smooth_triangle
  141. *
  142. * INPUT
  143. *   
  144. * OUTPUT
  145. *   
  146. * RETURNS
  147. *   
  148. * AUTHOR
  149. *
  150. *   POV-Ray Team
  151. *   
  152. * DESCRIPTION
  153. *
  154. *   -
  155. *
  156. * CHANGES
  157. *
  158. *   -
  159. *
  160. ******************************************************************************/
  161.  
  162. static void compute_smooth_triangle(Triangle)
  163. SMOOTH_TRIANGLE *Triangle;
  164. {
  165.   VECTOR P3MinusP2, VTemp1, VTemp2;
  166.   DBL x, y, z, uDenominator, Proj;
  167.  
  168.   VSub(P3MinusP2, Triangle->P3, Triangle->P2);
  169.  
  170.   x = fabs(P3MinusP2[X]);
  171.   y = fabs(P3MinusP2[Y]);
  172.   z = fabs(P3MinusP2[Z]);
  173.  
  174.   Triangle->vAxis = max3_coordinate(x, y, z);
  175.  
  176.   VSub(VTemp1, Triangle->P2, Triangle->P3);
  177.  
  178.   VNormalize(VTemp1, VTemp1);
  179.  
  180.   VSub(VTemp2, Triangle->P1, Triangle->P3);
  181.  
  182.   VDot(Proj, VTemp2, VTemp1);
  183.  
  184.   VScaleEq(VTemp1, Proj);
  185.  
  186.   VSub(Triangle->Perp, VTemp1, VTemp2);
  187.  
  188.   VNormalize(Triangle->Perp, Triangle->Perp);
  189.  
  190.   VDot(uDenominator, VTemp2, Triangle->Perp);
  191.  
  192.   VInverseScaleEq(Triangle->Perp, -uDenominator);
  193. }
  194.  
  195.  
  196.  
  197. /*****************************************************************************
  198. *
  199. * FUNCTION
  200. *
  201. *   Compute_Triangle
  202. *
  203. * INPUT
  204. *   
  205. * OUTPUT
  206. *   
  207. * RETURNS
  208. *   
  209. * AUTHOR
  210. *
  211. *   POV-Ray Team
  212. *   
  213. * DESCRIPTION
  214. *
  215. *   -
  216. *
  217. * CHANGES
  218. *
  219. *   -
  220. *
  221. ******************************************************************************/
  222.  
  223. int Compute_Triangle(Triangle,Smooth)
  224. TRIANGLE *Triangle;
  225. int Smooth;
  226. {
  227.   int swap;
  228.   VECTOR V1, V2, Temp;
  229.   DBL Length;
  230.  
  231.   VSub(V1, Triangle->P1, Triangle->P2);
  232.   VSub(V2, Triangle->P3, Triangle->P2);
  233.  
  234.   VCross(Triangle->Normal_Vector, V1, V2);
  235.  
  236.   VLength(Length, Triangle->Normal_Vector);
  237.  
  238.   /* Set up a flag so we can ignore degenerate triangles */
  239.  
  240.   if (Length == 0.0)
  241.   {
  242.     Set_Flag(Triangle, DEGENERATE_FLAG);
  243.  
  244.     return(FALSE);
  245.   }
  246.  
  247.   /* Normalize the normal vector. */
  248.  
  249.   VInverseScaleEq(Triangle->Normal_Vector, Length);
  250.  
  251.   VDot(Triangle->Distance, Triangle->Normal_Vector, Triangle->P1);
  252.  
  253.   Triangle->Distance *= -1.0;
  254.  
  255.   find_triangle_dominant_axis(Triangle);
  256.  
  257.   swap = FALSE;
  258.  
  259.   switch (Triangle->Dominant_Axis)
  260.   {
  261.     case X:
  262.  
  263.       if ((Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[Z] - Triangle->P1[Z]) <
  264.           (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[Y] - Triangle->P1[Y]))
  265.       {
  266.         swap = TRUE;
  267.       }
  268.  
  269.       break;
  270.  
  271.     case Y:
  272.  
  273.       if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Z] - Triangle->P1[Z]) <
  274.           (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[X] - Triangle->P1[X]))
  275.       {
  276.         swap = TRUE;
  277.       }
  278.  
  279.       break;
  280.  
  281.     case Z:
  282.  
  283.       if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Y] - Triangle->P1[Y]) <
  284.           (Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[X] - Triangle->P1[X]))
  285.       {
  286.         swap = TRUE;
  287.       }
  288.  
  289.       break;
  290.   }
  291.  
  292.   if (swap)
  293.   {
  294.     Assign_Vector(Temp, Triangle->P2);
  295.     Assign_Vector(Triangle->P2, Triangle->P1);
  296.     Assign_Vector(Triangle->P1, Temp);
  297.  
  298.     if (Smooth)
  299.     {
  300.       Assign_Vector(Temp, ((SMOOTH_TRIANGLE *)Triangle)->N2);
  301.       Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N2, ((SMOOTH_TRIANGLE *)Triangle)->N1);
  302.       Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N1, Temp);
  303.     }
  304.   }
  305.  
  306.   if (Smooth)
  307.   {
  308.     compute_smooth_triangle((SMOOTH_TRIANGLE *)Triangle);
  309.   }
  310.  
  311.   /* Build the bounding information from the vertices. */
  312.  
  313.   Compute_Triangle_BBox(Triangle);
  314.  
  315.   return(TRUE);
  316. }
  317.  
  318.  
  319.  
  320. /*****************************************************************************
  321. *
  322. * FUNCTION
  323. *
  324. *   All_Triangle_Intersections
  325. *
  326. * INPUT
  327. *   
  328. * OUTPUT
  329. *   
  330. * RETURNS
  331. *   
  332. * AUTHOR
  333. *
  334. *   POV-Ray Team
  335. *   
  336. * DESCRIPTION
  337. *
  338. *   -
  339. *
  340. * CHANGES
  341. *
  342. *   -
  343. *
  344. ******************************************************************************/
  345.  
  346. static int All_Triangle_Intersections(Object, Ray, Depth_Stack)
  347. OBJECT *Object;
  348. RAY *Ray;
  349. ISTACK *Depth_Stack;
  350. {
  351.   DBL Depth;
  352.   VECTOR IPoint;
  353.  
  354.   if (Intersect_Triangle(Ray, (TRIANGLE *)Object, &Depth))
  355.   {
  356.     VEvaluateRay(IPoint, Ray->Initial, Depth, Ray->Direction);
  357.  
  358.     if (Point_In_Clip(IPoint,Object->Clip))
  359.     {
  360.       push_entry(Depth,IPoint,Object,Depth_Stack);
  361.  
  362.       return(TRUE);
  363.     }
  364.   }
  365.  
  366.   return(FALSE);
  367. }
  368.  
  369.  
  370.  
  371. /*****************************************************************************
  372. *
  373. * FUNCTION
  374. *
  375. *   Intersect_Triangle
  376. *
  377. * INPUT
  378. *   
  379. * OUTPUT
  380. *   
  381. * RETURNS
  382. *   
  383. * AUTHOR
  384. *
  385. *   POV-Ray Team
  386. *   
  387. * DESCRIPTION
  388. *
  389. *   -
  390. *
  391. * CHANGES
  392. *
  393. *   -
  394. *
  395. ******************************************************************************/
  396.  
  397. static int Intersect_Triangle(Ray, Triangle, Depth)
  398. RAY *Ray;
  399. TRIANGLE *Triangle;
  400. DBL *Depth;
  401. {
  402.   DBL NormalDotOrigin, NormalDotDirection;
  403.   DBL s, t;
  404.  
  405.   Increase_Counter(stats[Ray_Triangle_Tests]);
  406.  
  407.   if (Test_Flag(Triangle, DEGENERATE_FLAG))
  408.   {
  409.     return(FALSE);
  410.   }
  411.  
  412.   VDot(NormalDotDirection, Triangle->Normal_Vector, Ray->Direction);
  413.  
  414.   if (fabs(NormalDotDirection) < EPSILON)
  415.   {
  416.     return(FALSE);
  417.   }
  418.  
  419.   VDot(NormalDotOrigin, Triangle->Normal_Vector, Ray->Initial);
  420.  
  421.   *Depth = -(Triangle->Distance + NormalDotOrigin) / NormalDotDirection;
  422.  
  423.   if ((*Depth < DEPTH_TOLERANCE) || (*Depth > Max_Distance))
  424.   {
  425.     return(FALSE);
  426.   }
  427.  
  428.   switch (Triangle->Dominant_Axis)
  429.   {
  430.     case X:
  431.  
  432.       s = Ray->Initial[Y] + *Depth * Ray->Direction[Y];
  433.       t = Ray->Initial[Z] + *Depth * Ray->Direction[Z];
  434.  
  435.       if ((Triangle->P2[Y] - s) * (Triangle->P2[Z] - Triangle->P1[Z]) <
  436.           (Triangle->P2[Z] - t) * (Triangle->P2[Y] - Triangle->P1[Y]))
  437.       {
  438.         return(FALSE);
  439.       }
  440.  
  441.       if ((Triangle->P3[Y] - s) * (Triangle->P3[Z] - Triangle->P2[Z]) <
  442.           (Triangle->P3[Z] - t) * (Triangle->P3[Y] - Triangle->P2[Y]))
  443.       {
  444.         return(FALSE);
  445.       }
  446.  
  447.       if ((Triangle->P1[Y] - s) * (Triangle->P1[Z] - Triangle->P3[Z]) <
  448.           (Triangle->P1[Z] - t) * (Triangle->P1[Y] - Triangle->P3[Y]))
  449.       {
  450.         return(FALSE);
  451.       }
  452.  
  453.       Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
  454.  
  455.       return(TRUE);
  456.  
  457.     case Y:
  458.  
  459.       s = Ray->Initial[X] + *Depth * Ray->Direction[X];
  460.       t = Ray->Initial[Z] + *Depth * Ray->Direction[Z];
  461.  
  462.       if ((Triangle->P2[X] - s) * (Triangle->P2[Z] - Triangle->P1[Z]) <
  463.           (Triangle->P2[Z] - t) * (Triangle->P2[X] - Triangle->P1[X]))
  464.       {
  465.         return(FALSE);
  466.       }
  467.  
  468.       if ((Triangle->P3[X] - s) * (Triangle->P3[Z] - Triangle->P2[Z]) <
  469.           (Triangle->P3[Z] - t) * (Triangle->P3[X] - Triangle->P2[X]))
  470.       {
  471.         return(FALSE);
  472.       }
  473.  
  474.       if ((Triangle->P1[X] - s) * (Triangle->P1[Z] - Triangle->P3[Z]) <
  475.           (Triangle->P1[Z] - t) * (Triangle->P1[X] - Triangle->P3[X]))
  476.       {
  477.         return(FALSE);
  478.       }
  479.  
  480.       Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
  481.  
  482.       return(TRUE);
  483.  
  484.     case Z:
  485.  
  486.       s = Ray->Initial[X] + *Depth * Ray->Direction[X];
  487.       t = Ray->Initial[Y] + *Depth * Ray->Direction[Y];
  488.  
  489.       if ((Triangle->P2[X] - s) * (Triangle->P2[Y] - Triangle->P1[Y]) <
  490.           (Triangle->P2[Y] - t) * (Triangle->P2[X] - Triangle->P1[X]))
  491.       {
  492.         return(FALSE);
  493.       }
  494.  
  495.       if ((Triangle->P3[X] - s) * (Triangle->P3[Y] - Triangle->P2[Y]) <
  496.           (Triangle->P3[Y] - t) * (Triangle->P3[X] - Triangle->P2[X]))
  497.       {
  498.         return(FALSE);
  499.       }
  500.  
  501.       if ((Triangle->P1[X] - s) * (Triangle->P1[Y] - Triangle->P3[Y]) <
  502.           (Triangle->P1[Y] - t) * (Triangle->P1[X] - Triangle->P3[X]))
  503.       {
  504.         return(FALSE);
  505.       }
  506.  
  507.       Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
  508.  
  509.       return(TRUE);
  510.   }
  511.  
  512.   return(FALSE);
  513. }
  514.  
  515.  
  516.  
  517. /*****************************************************************************
  518. *
  519. * FUNCTION
  520. *
  521. *   Inside_Triangle
  522. *
  523. * INPUT
  524. *   
  525. * OUTPUT
  526. *   
  527. * RETURNS
  528. *   
  529. * AUTHOR
  530. *
  531. *   POV-Ray Team
  532. *   
  533. * DESCRIPTION
  534. *
  535. *   -
  536. *
  537. * CHANGES
  538. *
  539. *   -
  540. *
  541. ******************************************************************************/
  542.  
  543. static int Inside_Triangle(IPoint, Object)
  544. VECTOR IPoint;
  545. OBJECT *Object;
  546. {
  547.   return(FALSE);
  548. }
  549.  
  550.  
  551.  
  552. /*****************************************************************************
  553. *
  554. * FUNCTION
  555. *
  556. *   Triangle_Normal
  557. *
  558. * INPUT
  559. *   
  560. * OUTPUT
  561. *   
  562. * RETURNS
  563. *   
  564. * AUTHOR
  565. *
  566. *   POV-Ray Team
  567. *   
  568. * DESCRIPTION
  569. *
  570. *   -
  571. *
  572. * CHANGES
  573. *
  574. *   -
  575. *
  576. ******************************************************************************/
  577.  
  578. static void Triangle_Normal(Result, Object, Inter)
  579. OBJECT *Object;
  580. VECTOR Result;
  581. INTERSECTION *Inter;
  582. {
  583.   Assign_Vector(Result, ((TRIANGLE *)Object)->Normal_Vector);
  584. }
  585.  
  586.  
  587.  
  588. /*****************************************************************************
  589. *
  590. * FUNCTION
  591. *
  592. *   Smooth_Triangle_Normal
  593. *
  594. * INPUT
  595. *   
  596. * OUTPUT
  597. *   
  598. * RETURNS
  599. *   
  600. * AUTHOR
  601. *
  602. *   POV-Ray Team
  603. *   
  604. * DESCRIPTION
  605. *
  606. *   Calculate the Phong-interpolated vector within the triangle
  607. *   at the given intersection point. The math for this is a bit
  608. *   bizarre:
  609. *
  610. *      -         P1
  611. *      |        /|\ \
  612. *      |       / |Perp\
  613. *      |      /  V  \   \
  614. *      |     /   |    \   \
  615. *    u |    /____|_____PI___\
  616. *      |   /     |       \    \
  617. *      -  P2-----|--------|----P3
  618. *                Pbase    PIntersect
  619. *          |-------------------|
  620. *                         v
  621. *
  622. *   Triangle->Perp is a unit vector from P1 to Pbase. We calculate
  623. *
  624. *   u = (PI - P1) DOT Perp / ((P3 - P1) DOT Perp).
  625. *
  626. *   We then calculate where the line from P1 to PI intersects the line P2 to P3:
  627. *   PIntersect = (PI - P1)/u.
  628. *
  629. *   We really only need one coordinate of PIntersect.  We then calculate v as:
  630. *
  631. *        v = PIntersect[X] / (P3[X] - P2[X])
  632. *   or   v = PIntersect[Y] / (P3[Y] - P2[Y])
  633. *   or   v = PIntersect[Z] / (P3[Z] - P2[Z])
  634. *
  635. *   depending on which calculation will give us the best answers.
  636. *
  637. *   Once we have u and v, we can perform the normal interpolation as:
  638. *
  639. *     NTemp1 = N1 + u(N2 - N1);
  640. *     NTemp2 = N1 + u(N3 - N1);
  641. *     Result = normalize (NTemp1 + v(NTemp2 - NTemp1))
  642. *
  643. *   As always, any values which are constant for the triangle are cached
  644. *   in the triangle.
  645. *
  646. * CHANGES
  647. *
  648. *   -
  649. *
  650. ******************************************************************************/
  651.  
  652. static void Smooth_Triangle_Normal(Result, Object, Inter)
  653. OBJECT *Object;
  654. VECTOR Result;
  655. INTERSECTION *Inter;
  656. {
  657.   int Axis;
  658.   DBL u, v;
  659.   VECTOR PIMinusP1;
  660.   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  661.  
  662.   VSub(PIMinusP1, Inter->IPoint, Triangle->P1);
  663.  
  664.   VDot(u, PIMinusP1, Triangle->Perp);
  665.  
  666.   if (u < EPSILON)
  667.   {
  668.     Assign_Vector(Result, Triangle->N1);
  669.  
  670.     return;
  671.   }
  672.  
  673.   Axis = Triangle->vAxis;
  674.  
  675.   v = (PIMinusP1[Axis] / u + Triangle->P1[Axis] - Triangle->P2[Axis]) / (Triangle->P3[Axis] - Triangle->P2[Axis]);
  676.  
  677.   /* This is faster. [DB 8/94] */
  678.  
  679.   Result[X] = Triangle->N1[X] + u * (Triangle->N2[X] - Triangle->N1[X] + v * (Triangle->N3[X] - Triangle->N2[X]));
  680.   Result[Y] = Triangle->N1[Y] + u * (Triangle->N2[Y] - Triangle->N1[Y] + v * (Triangle->N3[Y] - Triangle->N2[Y]));
  681.   Result[Z] = Triangle->N1[Z] + u * (Triangle->N2[Z] - Triangle->N1[Z] + v * (Triangle->N3[Z] - Triangle->N2[Z]));
  682.  
  683.   VNormalize(Result, Result);
  684. }
  685.  
  686.  
  687.  
  688. /*****************************************************************************
  689. *
  690. * FUNCTION
  691. *
  692. *   Translate_Triangle
  693. *
  694. * INPUT
  695. *   
  696. * OUTPUT
  697. *   
  698. * RETURNS
  699. *   
  700. * AUTHOR
  701. *
  702. *   POV-Ray Team
  703. *   
  704. * DESCRIPTION
  705. *
  706. *   -
  707. *
  708. * CHANGES
  709. *
  710. *   -
  711. *
  712. ******************************************************************************/
  713.  
  714. static void Translate_Triangle(Object, Vector, Trans)
  715. OBJECT *Object;
  716. VECTOR Vector;
  717. TRANSFORM *Trans;
  718. {
  719.   TRIANGLE *Triangle = (TRIANGLE *)Object;
  720.   VECTOR Translation;
  721.  
  722.   if (!Test_Flag(Triangle, DEGENERATE_FLAG))
  723.   {
  724.     VEvaluate(Translation, Triangle->Normal_Vector, Vector);
  725.  
  726.     Triangle->Distance -= Translation[X] + Translation[Y] + Translation[Z];
  727.  
  728.     VAddEq(Triangle->P1, Vector);
  729.     VAddEq(Triangle->P2, Vector);
  730.     VAddEq(Triangle->P3, Vector);
  731.  
  732.     Compute_Triangle(Triangle, FALSE);
  733.   }
  734. }
  735.  
  736.  
  737.  
  738. /*****************************************************************************
  739. *
  740. * FUNCTION
  741. *
  742. *   Rotate_Triangle
  743. *
  744. * INPUT
  745. *
  746. * OUTPUT
  747. *
  748. * RETURNS
  749. *
  750. * AUTHOR
  751. *
  752. *   POV-Ray Team
  753. *
  754. * DESCRIPTION
  755. *
  756. *   -
  757. *
  758. * CHANGES
  759. *
  760. *   -
  761. *
  762. ******************************************************************************/
  763.  
  764. static void Rotate_Triangle(Object, Vector, Trans)
  765. OBJECT *Object;
  766. VECTOR Vector;
  767. TRANSFORM *Trans;
  768. {
  769.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  770.   {
  771.     Transform_Triangle(Object, Trans);
  772.   }
  773. }
  774.  
  775.  
  776.  
  777. /*****************************************************************************
  778. *
  779. * FUNCTION
  780. *
  781. *   Scale_Triangle
  782. *
  783. * INPUT
  784. *
  785. * OUTPUT
  786. *
  787. * RETURNS
  788. *
  789. * AUTHOR
  790. *
  791. *   POV-Ray Team
  792. *
  793. * DESCRIPTION
  794. *
  795. *   -
  796. *
  797. * CHANGES
  798. *
  799. *   -
  800. *
  801. ******************************************************************************/
  802.  
  803. static void Scale_Triangle(Object, Vector, Trans)
  804. OBJECT *Object;
  805. VECTOR Vector;
  806. TRANSFORM *Trans;
  807. {
  808.   DBL Length;
  809.   TRIANGLE *Triangle = (TRIANGLE *)Object;
  810.  
  811.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  812.   {
  813.     Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X];
  814.     Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y];
  815.     Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z];
  816.  
  817.     VLength(Length, Triangle->Normal_Vector);
  818.  
  819.     VInverseScaleEq(Triangle->Normal_Vector, Length);
  820.  
  821.     Triangle->Distance /= Length;
  822.  
  823.     VEvaluateEq(Triangle->P1, Vector);
  824.     VEvaluateEq(Triangle->P2, Vector);
  825.     VEvaluateEq(Triangle->P3, Vector);
  826.  
  827.     Compute_Triangle(Triangle, FALSE);
  828.   }
  829. }
  830.  
  831.  
  832.  
  833. /*****************************************************************************
  834. *
  835. * FUNCTION
  836. *
  837. *   Transfrom_Triangle
  838. *
  839. * INPUT
  840. *   
  841. * OUTPUT
  842. *   
  843. * RETURNS
  844. *
  845. * AUTHOR
  846. *
  847. *   POV-Ray Team
  848. *
  849. * DESCRIPTION
  850. *
  851. *   -
  852. *
  853. * CHANGES
  854. *
  855. *   -
  856. *
  857. ******************************************************************************/
  858.  
  859. static void Transform_Triangle(Object, Trans)
  860. OBJECT *Object;
  861. TRANSFORM *Trans;
  862. {
  863.   TRIANGLE *Triangle = (TRIANGLE *)Object;
  864.  
  865.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  866.   {
  867.     MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
  868.     MTransPoint(Triangle->P1, Triangle->P1, Trans);
  869.     MTransPoint(Triangle->P2, Triangle->P2, Trans);
  870.     MTransPoint(Triangle->P3, Triangle->P3, Trans);
  871.  
  872.     Compute_Triangle(Triangle, FALSE);
  873.   }
  874. }
  875.  
  876.  
  877.  
  878. /*****************************************************************************
  879. *
  880. * FUNCTION
  881. *
  882. *   Invert_Triangle
  883. *
  884. * INPUT
  885. *   
  886. * OUTPUT
  887. *   
  888. * RETURNS
  889. *   
  890. * AUTHOR
  891. *
  892. *   POV-Ray Team
  893. *   
  894. * DESCRIPTION
  895. *
  896. *   -
  897. *
  898. * CHANGES
  899. *
  900. *   -
  901. *
  902. ******************************************************************************/
  903.  
  904. static void Invert_Triangle(Object)
  905. OBJECT *Object;
  906. {
  907. }
  908.  
  909.  
  910.  
  911. /*****************************************************************************
  912. *
  913. * FUNCTION
  914. *
  915. *   Create_Triangle
  916. *
  917. * INPUT
  918. *   
  919. * OUTPUT
  920. *   
  921. * RETURNS
  922. *   
  923. * AUTHOR
  924. *
  925. *   POV-Ray Team
  926. *   
  927. * DESCRIPTION
  928. *
  929. *   -
  930. *
  931. * CHANGES
  932. *
  933. *   -
  934. *
  935. ******************************************************************************/
  936.  
  937. TRIANGLE *Create_Triangle()
  938. {
  939.   TRIANGLE *New;
  940.  
  941.   New = (TRIANGLE *)POV_MALLOC(sizeof(TRIANGLE), "triangle");
  942.  
  943.   INIT_OBJECT_FIELDS(New,TRIANGLE_OBJECT,&Triangle_Methods)
  944.  
  945.   Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
  946.  
  947.   New->Distance = 0.0;
  948.  
  949.   Make_Vector(New->P1, 0.0, 0.0, 0.0);
  950.   Make_Vector(New->P2, 1.0, 0.0, 0.0);
  951.   Make_Vector(New->P3, 0.0, 1.0, 0.0);
  952.  
  953.   /*
  954.    * NOTE: Dominant_Axis is computed when Parse_Triangle calls
  955.    * Compute_Triangle. vAxis is used only for smooth triangles.
  956.    */
  957.  
  958.   return(New);
  959. }
  960.  
  961.  
  962.  
  963. /*****************************************************************************
  964. *
  965. * FUNCTION
  966. *
  967. *   Copy_Triangle
  968. *
  969. * INPUT
  970. *   
  971. * OUTPUT
  972. *   
  973. * RETURNS
  974. *   
  975. * AUTHOR
  976. *
  977. *   POV-Ray Team
  978. *   
  979. * DESCRIPTION
  980. *
  981. *   -
  982. *
  983. * CHANGES
  984. *
  985. *   -
  986. *
  987. ******************************************************************************/
  988.  
  989. static void *Copy_Triangle(Object)
  990. OBJECT *Object;
  991. {
  992.   TRIANGLE *New;
  993.  
  994.   New = Create_Triangle();
  995.  
  996.   *New = *((TRIANGLE *)Object);
  997.  
  998.   return(New);
  999. }
  1000.  
  1001.  
  1002.  
  1003. /*****************************************************************************
  1004. *
  1005. * FUNCTION
  1006. *
  1007. *   Destroy_Triangle
  1008. *
  1009. * INPUT
  1010. *   
  1011. * OUTPUT
  1012. *   
  1013. * RETURNS
  1014. *   
  1015. * AUTHOR
  1016. *
  1017. *   POV-Ray Team
  1018. *   
  1019. * DESCRIPTION
  1020. *
  1021. *   -
  1022. *
  1023. * CHANGES
  1024. *
  1025. *   -
  1026. *
  1027. ******************************************************************************/
  1028.  
  1029. static void Destroy_Triangle(Object)
  1030. OBJECT *Object;
  1031. {
  1032.   POV_FREE (Object);
  1033. }
  1034.  
  1035.  
  1036.  
  1037. /*****************************************************************************
  1038. *
  1039. * FUNCTION
  1040. *
  1041. *   Translate_Smooth_Triangle
  1042. *
  1043. * INPUT
  1044. *   
  1045. * OUTPUT
  1046. *   
  1047. * RETURNS
  1048. *   
  1049. * AUTHOR
  1050. *
  1051. *   POV-Ray Team
  1052. *   
  1053. * DESCRIPTION
  1054. *
  1055. *   -
  1056. *
  1057. * CHANGES
  1058. *
  1059. *   -
  1060. *
  1061. ******************************************************************************/
  1062.  
  1063. static void Translate_Smooth_Triangle(Object, Vector, Trans)
  1064. OBJECT *Object;
  1065. VECTOR Vector;
  1066. TRANSFORM *Trans;
  1067. {
  1068.   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  1069.   VECTOR Translation;
  1070.  
  1071.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  1072.   {
  1073.     VEvaluate(Translation, Triangle->Normal_Vector, Vector);
  1074.  
  1075.     Triangle->Distance -= Translation[X] + Translation[Y] + Translation[Z];
  1076.  
  1077.     VAddEq(Triangle->P1, Vector);
  1078.     VAddEq(Triangle->P2, Vector);
  1079.     VAddEq(Triangle->P3, Vector);
  1080.  
  1081.     Compute_Triangle((TRIANGLE *)Triangle, TRUE);
  1082.   }
  1083. }
  1084.  
  1085.  
  1086.  
  1087. /*****************************************************************************
  1088. *
  1089. * FUNCTION
  1090. *
  1091. *   Rotate_Smooth_Triangle
  1092. *
  1093. * INPUT
  1094. *   
  1095. * OUTPUT
  1096. *   
  1097. * RETURNS
  1098. *   
  1099. * AUTHOR
  1100. *
  1101. *   POV-Ray Team
  1102. *
  1103. * DESCRIPTION
  1104. *
  1105. *   -
  1106. *
  1107. * CHANGES
  1108. *
  1109. *   -
  1110. *
  1111. ******************************************************************************/
  1112.  
  1113. static void Rotate_Smooth_Triangle(Object, Vector, Trans)
  1114. OBJECT *Object;
  1115. VECTOR Vector;
  1116. TRANSFORM *Trans;
  1117. {
  1118.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  1119.   {
  1120.     Transform_Smooth_Triangle(Object, Trans);
  1121.   }
  1122. }
  1123.  
  1124.  
  1125.  
  1126. /*****************************************************************************
  1127. *
  1128. * FUNCTION
  1129. *
  1130. *   Scale_Smooth_Triangle
  1131. *
  1132. * INPUT
  1133. *   
  1134. * OUTPUT
  1135. *   
  1136. * RETURNS
  1137. *   
  1138. * AUTHOR
  1139. *
  1140. *   POV-Ray Team
  1141. *   
  1142. * DESCRIPTION
  1143. *
  1144. *   -
  1145. *
  1146. * CHANGES
  1147. *
  1148. *   -
  1149. *
  1150. ******************************************************************************/
  1151.  
  1152. static void Scale_Smooth_Triangle(Object, Vector, Trans)
  1153. OBJECT *Object;
  1154. VECTOR Vector;
  1155. TRANSFORM *Trans;
  1156. {
  1157.   DBL Length;
  1158.   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  1159.  
  1160.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  1161.   {
  1162.     Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X];
  1163.     Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y];
  1164.     Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z];
  1165.  
  1166.     VLength(Length, Triangle->Normal_Vector);
  1167.     VScaleEq(Triangle->Normal_Vector, 1.0 / Length);
  1168.     Triangle->Distance /= Length;
  1169.  
  1170.     VEvaluateEq(Triangle->P1, Vector);
  1171.     VEvaluateEq(Triangle->P2, Vector);
  1172.     VEvaluateEq(Triangle->P3, Vector);
  1173.  
  1174.     Compute_Triangle((TRIANGLE *)Triangle,TRUE);
  1175.   }
  1176. }
  1177.  
  1178.  
  1179.  
  1180. /*****************************************************************************
  1181. *
  1182. * FUNCTION
  1183. *
  1184. *   Transform_Smooth_Triangle
  1185. *
  1186. * INPUT
  1187. *   
  1188. * OUTPUT
  1189. *   
  1190. * RETURNS
  1191. *   
  1192. * AUTHOR
  1193. *
  1194. *   POV-Ray Team
  1195. *   
  1196. * DESCRIPTION
  1197. *
  1198. *   -
  1199. *
  1200. * CHANGES
  1201. *
  1202. *   -
  1203. *
  1204. ******************************************************************************/
  1205.  
  1206. static void Transform_Smooth_Triangle(Object, Trans)
  1207. OBJECT *Object;
  1208. TRANSFORM *Trans;
  1209. {
  1210.   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  1211.  
  1212.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  1213.   {
  1214.     MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
  1215.     MTransPoint(Triangle->P1, Triangle->P1, Trans);
  1216.     MTransPoint(Triangle->P2, Triangle->P2, Trans);
  1217.     MTransPoint(Triangle->P3, Triangle->P3, Trans);
  1218.     MTransPoint(Triangle->N1, Triangle->N1, Trans);
  1219.     MTransPoint(Triangle->N2, Triangle->N2, Trans);
  1220.     MTransPoint(Triangle->N3, Triangle->N3, Trans);
  1221.  
  1222.     Compute_Triangle((TRIANGLE *)Triangle, TRUE);
  1223.   }
  1224. }
  1225.  
  1226.  
  1227.  
  1228. /*****************************************************************************
  1229. *
  1230. * FUNCTION
  1231. *
  1232. *   Invert_Smooth_Triangle
  1233. *
  1234. * INPUT
  1235. *   
  1236. * OUTPUT
  1237. *   
  1238. * RETURNS
  1239. *   
  1240. * AUTHOR
  1241. *
  1242. *   POV-Ray Team
  1243. *   
  1244. * DESCRIPTION
  1245. *
  1246. *   -
  1247. *
  1248. * CHANGES
  1249. *
  1250. *   -
  1251. *
  1252. ******************************************************************************/
  1253.  
  1254. static void Invert_Smooth_Triangle(Object)
  1255. OBJECT *Object;
  1256. {
  1257. }
  1258.  
  1259.  
  1260.  
  1261. /*****************************************************************************
  1262. *
  1263. * FUNCTION
  1264. *
  1265. *   Create_Smooth_Triangle
  1266. *
  1267. * INPUT
  1268. *   
  1269. * OUTPUT
  1270. *   
  1271. * RETURNS
  1272. *   
  1273. * AUTHOR
  1274. *
  1275. *   POV-Ray Team
  1276. *   
  1277. * DESCRIPTION
  1278. *
  1279. *   -
  1280. *
  1281. * CHANGES
  1282. *
  1283. *   -
  1284. *
  1285. ******************************************************************************/
  1286.  
  1287. SMOOTH_TRIANGLE *Create_Smooth_Triangle()
  1288. {
  1289.   SMOOTH_TRIANGLE *New;
  1290.  
  1291.   New = (SMOOTH_TRIANGLE *)POV_MALLOC(sizeof(SMOOTH_TRIANGLE), "smooth triangle");
  1292.  
  1293.   INIT_OBJECT_FIELDS(New,SMOOTH_TRIANGLE_OBJECT,&Smooth_Triangle_Methods)
  1294.  
  1295.   Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
  1296.  
  1297.   New->Distance = 0.0;
  1298.  
  1299.   Make_Vector(New->P1, 0.0, 0.0, 0.0);
  1300.   Make_Vector(New->P2, 1.0, 0.0, 0.0);
  1301.   Make_Vector(New->P3, 0.0, 1.0, 0.0);
  1302.   Make_Vector(New->N1, 0.0, 1.0, 0.0);
  1303.   Make_Vector(New->N2, 0.0, 1.0, 0.0);
  1304.   Make_Vector(New->N3, 0.0, 1.0, 0.0);
  1305.  
  1306.   /*
  1307.    * NOTE: Dominant_Axis and vAxis are computed when
  1308.    * Parse_Triangle calls Compute_Triangle.
  1309.    */
  1310.  
  1311.   return(New);
  1312. }
  1313.  
  1314.  
  1315.  
  1316. /*****************************************************************************
  1317. *
  1318. * FUNCTION
  1319. *
  1320. *   Copy_Smooth_Triangle
  1321. *
  1322. * INPUT
  1323. *   
  1324. * OUTPUT
  1325. *   
  1326. * RETURNS
  1327. *   
  1328. * AUTHOR
  1329. *
  1330. *   POV-Ray Team
  1331. *   
  1332. * DESCRIPTION
  1333. *
  1334. *   -
  1335. *
  1336. * CHANGES
  1337. *
  1338. *   -
  1339. *
  1340. ******************************************************************************/
  1341.  
  1342. static void *Copy_Smooth_Triangle(Object)
  1343. OBJECT *Object;
  1344. {
  1345.   SMOOTH_TRIANGLE *New;
  1346.  
  1347.   New = Create_Smooth_Triangle();
  1348.  
  1349.   *New = *((SMOOTH_TRIANGLE *)Object);
  1350.  
  1351.   return(New);
  1352. }
  1353.  
  1354.  
  1355.  
  1356. /*****************************************************************************
  1357. *
  1358. * FUNCTION
  1359. *
  1360. *   Compute_Triangle_BBox
  1361. *
  1362. * INPUT
  1363. *
  1364. *   Triangle - Triangle
  1365. *   
  1366. * OUTPUT
  1367. *
  1368. *   Triangle
  1369. *   
  1370. * RETURNS
  1371. *   
  1372. * AUTHOR
  1373. *
  1374. *   Dieter Bayer
  1375. *   
  1376. * DESCRIPTION
  1377. *
  1378. *   Calculate the bounding box of a triangle.
  1379. *
  1380. * CHANGES
  1381. *
  1382. *   Aug 1994 : Creation.
  1383. *
  1384. ******************************************************************************/
  1385.  
  1386. void Compute_Triangle_BBox(Triangle)
  1387. TRIANGLE *Triangle;
  1388. {
  1389.   VECTOR Min, Max, Epsilon;
  1390.  
  1391.   Make_Vector(Epsilon, EPSILON, EPSILON, EPSILON);
  1392.  
  1393.   Min[X] = min3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
  1394.   Min[Y] = min3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
  1395.   Min[Z] = min3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);
  1396.  
  1397.   Max[X] = max3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
  1398.   Max[Y] = max3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
  1399.   Max[Z] = max3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);
  1400.  
  1401.   VSubEq(Min, Epsilon);
  1402.   VAddEq(Max, Epsilon);
  1403.  
  1404.   Make_BBox_from_min_max(Triangle->BBox, Min, Max);
  1405. }
  1406.  
  1407.  
  1408.